package tmhm.shemes;

import java.awt.Point;
import java.util.ArrayList;

import tmhm.components.*;
import tmhm.gui.*;


public class Mem1 {

    private static TSB TSBRDB;
    private static NOT NOTRDB;
    private static AND ANDrdMEM;
    private static IntToBools ABUSBits;
    private static AND ANDselect;
    private static NOT NOTselect;
    private static TSB TSBWRB;
    private static NOT NOTWRB;
    private static AND ANDwrMEM;
    private static MEM RAM;
    private static TSB TSBMEMout;
    private static TSB TSBFCB;
    private static NOT NOTFCB;
    private static GuiScheme gui;

    public static GuiScheme getGui() {
        return gui;
    }

    public static void init() {
        TSBRDB = new TSB();
        TSBRDB.getOut(0).setNumOfLines(1);
        TSBRDB.getOut(0).setIsBool();
        NOTRDB = new NOT();
        ANDrdMEM = new AND();

        ABUSBits = new IntToBools(16, 16);
        ANDselect = new AND(4);
        NOTselect = new NOT();

        TSBWRB = new TSB();
        TSBWRB.getOut(0).setNumOfLines(1);
        TSBWRB.getOut(0).setIsBool();
        NOTWRB = new NOT();
        ANDwrMEM = new AND();

        RAM = new MEM(64 * 1024); // 64 Kb
        RAM.getOut(0).setIsInt();
        RAM.getOut(0).setNumOfLines(8);
        RAM.setClock(1);
        TSBMEMout = new TSB();
        TSBMEMout.getOut(0).setNumOfLines(8);

        TSBFCB = new TSB();
        TSBFCB.getOut(0).setIsBool();
        NOTFCB = new NOT();

    }

    public static void connect() {
        TSBRDB.setInputPin(0, Bus1.NOTRDBUS());
        TSBRDB.setCtrl(new Pin(true));
        NOTRDB.setInputPin(0, TSBRDB.getOut(0));
        ANDrdMEM.setInputPin(0, NOTRDB.getOut(0));
        ANDrdMEM.setInputPin(1, NOTselect.getOut(0));

        ABUSBits.setInputPin(0, Bus1.ABUS());
        ANDselect.setInputPin(0, ABUSBits.getOut(12));
        ANDselect.setInputPin(1, ABUSBits.getOut(13));
        ANDselect.setInputPin(2, ABUSBits.getOut(14));
        ANDselect.setInputPin(3, ABUSBits.getOut(15));
        NOTselect.setInputPin(0, ANDselect.getOut(0));

        TSBWRB.setInputPin(0, Bus1.NOTWRBUS());
        TSBWRB.setCtrl(new Pin(true));
        NOTWRB.setInputPin(0, TSBWRB.getOut(0));
        ANDwrMEM.setInputPin(0, NOTselect.getOut(0));
        ANDwrMEM.setInputPin(1, NOTWRB.getOut(0));

        RAM.setRead(ANDrdMEM.getOut(0));
        RAM.setWrite(ANDwrMEM.getOut(0));
        RAM.setInputPin(0, Bus1.ABUS());
        RAM.setInputPin(1, Bus1.DBUS());
        TSBMEMout.setInputPin(0, RAM.getOut(0));
        TSBMEMout.setCtrl(Mem2.MEMout());
        Bus1.addOnDBUS(TSBMEMout.getOut(0));

        TSBFCB.setInputPin(0, new Pin(true));
        TSBFCB.setCtrl(Mem2.fcMEM());
        NOTFCB.setInputPin(0, TSBFCB.getOut(0));
        Bus1.addOnNOTFCBUS(NOTFCB.getOut(0));

    }

    public static void gui() {
        GuiLine line; // Pomocna promenljiva
        gui = new GuiScheme("tmhm/tmhm/images/Mem1.png");

        ArrayList<ArrayList<Point>> sections;
        ArrayList<Point> points;


        sections = new ArrayList<ArrayList<Point>>();
        points = new ArrayList<Point>();
        points.add(new Point(84, 142));
        points.add(new Point(103, 142));
        sections.add(points);
        line = new GuiLine(sections, Bus1.NOTRDBUS());
        gui.addLine(line);

        sections = new ArrayList<ArrayList<Point>>();
        points = new ArrayList<Point>();
        points.add(new Point(132, 142));
        points.add(new Point(162, 142));
        sections.add(points);
        line = new GuiLine(sections, NOTRDB.getOut(0));
        gui.addLine(line);

        sections = new ArrayList<ArrayList<Point>>();
        points = new ArrayList<Point>();
        points.add(new Point(87, 167));
        points.add(new Point(103, 167));
        sections.add(points);
        line = new GuiLine(sections, ABUSBits.getOut(12));
        gui.addLine(line);

        sections = new ArrayList<ArrayList<Point>>();
        points = new ArrayList<Point>();
        points.add(new Point(87, 180));
        points.add(new Point(103, 180));
        sections.add(points);
        line = new GuiLine(sections, ABUSBits.getOut(13));
        gui.addLine(line);

        sections = new ArrayList<ArrayList<Point>>();
        points = new ArrayList<Point>();
        points.add(new Point(87, 195));
        points.add(new Point(103, 195));
        sections.add(points);
        line = new GuiLine(sections, ABUSBits.getOut(14));
        gui.addLine(line);

        sections = new ArrayList<ArrayList<Point>>();
        points = new ArrayList<Point>();
        points.add(new Point(87, 208));
        points.add(new Point(103, 208));
        sections.add(points);
        line = new GuiLine(sections, ABUSBits.getOut(15));
        gui.addLine(line);

        sections = new ArrayList<ArrayList<Point>>();
        points = new ArrayList<Point>();
        points.add(new Point(131, 187));
        points.add(new Point(143, 187));
        points.add(new Point(143, 153));
        points.add(new Point(162, 153));
        sections.add(points);
        points = new ArrayList<Point>();
        points.add(new Point(143, 187));
        points.add(new Point(143, 254));
        points.add(new Point(162, 254));
        sections.add(points);
        line = new GuiLine(sections, NOTselect.getOut(0));
        gui.addLine(line);

        sections = new ArrayList<ArrayList<Point>>();
        points = new ArrayList<Point>();
        points.add(new Point(83, 267));
        points.add(new Point(103, 267));
        sections.add(points);
        line = new GuiLine(sections, Bus1.NOTWRBUS());
        gui.addLine(line);

        sections = new ArrayList<ArrayList<Point>>();
        points = new ArrayList<Point>();
        points.add(new Point(130, 266));
        points.add(new Point(162, 266));
        sections.add(points);
        line = new GuiLine(sections, NOTWRB.getOut(0));
        gui.addLine(line);

        sections = new ArrayList<ArrayList<Point>>();
        points = new ArrayList<Point>();
        points.add(new Point(184, 147));
        points.add(new Point(254, 147));
        points.add(new Point(254, 176));
        points.add(new Point(342, 176));
        sections.add(points);
        line = new GuiLine(sections, ANDrdMEM.getOut(0));
        gui.addLine(line);

        sections = new ArrayList<ArrayList<Point>>();
        points = new ArrayList<Point>();
        points.add(new Point(184, 261));
        points.add(new Point(253, 261));
        points.add(new Point(253, 195));
        points.add(new Point(342, 195));
        sections.add(points);
        line = new GuiLine(sections, ANDwrMEM.getOut(0));
        gui.addLine(line);

        sections = new ArrayList<ArrayList<Point>>();
        points = new ArrayList<Point>();
        points.add(new Point(147, 355));
        points.add(new Point(147, 365));
        sections.add(points);
        line = new GuiLine(sections, Mem2.fcMEM());
        gui.addLine(line);

        sections = new ArrayList<ArrayList<Point>>();
        points = new ArrayList<Point>();
        points.add(new Point(191, 371));
        points.add(new Point(158, 371));
        sections.add(points);
        line = new GuiLine(sections, new Pin(true));
        gui.addLine(line);

        sections = new ArrayList<ArrayList<Point>>();
        points = new ArrayList<Point>();
        points.add(new Point(131, 371));
        points.add(new Point(111, 371));
        sections.add(points);
        line = new GuiLine(sections, NOTFCB.getOut(0));
        gui.addLine(line);

        sections = new ArrayList<ArrayList<Point>>();
        points = new ArrayList<Point>();
        points.add(new Point(443, 68));
        points.add(new Point(443, 136));
        sections.add(points);
        points = new ArrayList<Point>();
        points.add(new Point(445, 68));
        points.add(new Point(445, 136));
        sections.add(points);
        line = new GuiLine(sections, Bus1.ABUS());
        gui.addLine(line);

        sections = new ArrayList<ArrayList<Point>>();
        points = new ArrayList<Point>();
        points.add(new Point(616, 68));
        points.add(new Point(616, 368));
        sections.add(points);
        points = new ArrayList<Point>();
        points.add(new Point(618, 68));
        points.add(new Point(618, 380));
        sections.add(points);
        points = new ArrayList<Point>();
        points.add(new Point(615, 185));
        points.add(new Point(531, 185));
        sections.add(points);
        line = new GuiLine(sections, Bus1.DBUS());
        gui.addLine(line);

        sections = new ArrayList<ArrayList<Point>>();
        points = new ArrayList<Point>();
        points.add(new Point(437, 233));
        points.add(new Point(437, 286));
        points.add(new Point(521, 286));
        sections.add(points);
        line = new GuiLine(sections, RAM.getOut(0));
        gui.addLine(line);

        sections = new ArrayList<ArrayList<Point>>();
        points = new ArrayList<Point>();
        points.add(new Point(531, 301));
        points.add(new Point(531, 291));
        sections.add(points);
        line = new GuiLine(sections, Mem2.MEMout());
        gui.addLine(line);

        sections = new ArrayList<ArrayList<Point>>();
        points = new ArrayList<Point>();
        points.add(new Point(542, 286));
        points.add(new Point(615, 286));
        sections.add(points);
        line = new GuiLine(sections, TSBMEMout.getOut(0));
        gui.addLine(line);
        
        //LABELE:
        gui.addLabel(new GuiLabel(449, 91, Bus1.ABUS()));
        gui.addLabel(new GuiLabel(622, 91, Bus1.DBUS()));
        gui.addLabel(new GuiLabel(447, 248, RAM.getOut(0)));
        gui.addLabel(new GuiLabel(570, 181, Bus1.DBUS()));
        gui.addLabel(new GuiLabel(570, 282, TSBMEMout.getOut(0)));
    }

    public static Pin rdMEM() {
        return ANDrdMEM.getOut(0);
    }

    public static Pin wrMEM() {
        return ANDwrMEM.getOut(0);
    }

    public static void writeMEM(int adress, int data) {
        RAM.write(adress, data);
    }

    public static int readMEM(int adress) {
        return RAM.read(adress);
    }

    public static MEM getMEM() {
        return RAM;
    }
}
